package com.ifp.opengate.boot.utils;

import java.nio.charset.StandardCharsets;
import java.util.Map;

import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilterChain;

import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

/**
 * webflux forward util
 * 
 * @author zzh
 */
public class WebFluxUtil {
    /**
     * 重定向
     * 
     * @param forwardToPath: forward target path that begin with /.
     * @param exchange: the current source server exchange
     * @param forwardAttrs : the attributes that added to forward Exchange.
     * @return Mono<Void> to signal forwarding request completed.
     */
    public static Mono<Void> forward(String forwardToPath, ServerWebExchange exchange,
        Map<String, Object> forwardAttrs) {
        WebFilterChain webFilterChain = (WebFilterChain)exchange.getAttributes().get("filterchain");
        ServerHttpRequest forwardReq = exchange.getRequest().mutate().path(forwardToPath).build();
        ServerWebExchange forwardExchange = exchange.mutate().request(forwardReq).build();
        if (null != forwardAttrs && !forwardAttrs.isEmpty()) {
            forwardExchange.getAttributes().putAll(forwardAttrs);
        }
        return webFilterChain.filter(forwardExchange);
    }

    /**
     * 利用exchange直接返回值
     * 
     * @param exchange
     * @param recMsg
     * @param chain
     * @return
     */
    public static Mono<Void> writeFlux(ServerWebExchange exchange, String recMsg, GatewayFilterChain chain) {
        ServerHttpResponse response = exchange.getResponse();
        response.setStatusCode(HttpStatus.OK);
        response.getHeaders().setContentType(MediaType.APPLICATION_JSON_UTF8);
        byte[] bytes = recMsg.getBytes(StandardCharsets.UTF_8);
        DataBuffer buffer = response.bufferFactory().wrap(bytes);
        return response.writeWith(Flux.just(buffer)).then(chain.filter(exchange));
    }
}
